﻿using System;
using System.ServiceProcess;
using Config.Keede.Library;
using log4net;
using System.Configuration;
using System.Linq;
using System.Reflection;
using Keede.RabbitMQ;
using System.Collections.Generic;

namespace Keede.Rabbitmq.HandleService
{
    static class Program
    {
        static TaskHandleController _taskHandler;

        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        static void Main(string[] args)
        {
            var zookeeperAddr = ConfigurationManager.AppSettings["ZOOKEEPERADDR"];
            var configPath = ConfigurationManager.AppSettings["CONFIGPATH"];

            ConfManager.Init(zookeeperAddr, configPath);
            ConfManager.ValueChanged += ConfManager_ValueChanged;

            ApplicationStart();

            if (!Environment.UserInteractive)//Windows Service
            {
                RunAsService();
                return;
            }

            string exeArg;
            if (args == null || args.Length < 1)
            {
                Console.WriteLine("Welcome to service console!");

                Console.WriteLine("Please press a key to continue...");
                Console.WriteLine("-[r]: Run this application as a console application;");
                Console.WriteLine("-[i]: Install this application as a Windows Service;");
                Console.WriteLine("-[u]: Uninstall this Windows Service application;");
                while (true)
                {
                    exeArg = Console.ReadKey().KeyChar.ToString();
                    Console.WriteLine();

                    if (Run(exeArg, null))
                        break;
                }
            }
            else
            {
                exeArg = args[0];

                if (!string.IsNullOrEmpty(exeArg))
                    exeArg = exeArg.TrimStart('-');

                Run(exeArg, args);
            }

            Console.ReadLine();
        }

        private static void ConfManager_ValueChanged(object sender, ConfigValueChangedEventArgs args)
        {
            Console.WriteLine($"Name:{args.Name},OldValue:{args.OldValue},CurrentValue:{args.CurrentValue}");
        }

        private static bool Run(string exeArg, string[] startArgs)
        {
            switch (exeArg.ToLower())
            {
                case ("i"):
                    SelfInstaller.InstallMe();
                    return true;

                case ("u"):
                    SelfInstaller.UninstallMe();
                    return true;

                case ("r"):
                    RunAsConsole();
                    return true;

                default:
                    Console.WriteLine("Invalid argument!");
                    return false;
            }
        }



        static void RunAsConsole()
        {
            Console.WriteLine($"Welcome to {ConfManager.GetAppsetting("servicename")} service!");
            _taskHandler = new TaskHandleController();
            _taskHandler.Start();

            Console.ReadLine();
            Console.WriteLine($"The {ConfManager.GetAppsetting("servicename")} service has been stopped!");
            Console.ReadLine();
        }

        static void RunAsService()
        {
            _taskHandler = new TaskHandleController();
            ServiceBase[] servicesToRun = new ServiceBase[] { new TaskHandleService(_taskHandler) };
            ServiceBase.Run(servicesToRun);
        }

        static void ApplicationStart()
        {
            var _conf = ConfigurationManager.GetSection("handleService") as HandleServiceConfig;
            if (string.IsNullOrEmpty(_conf?.ApplicationInit?.Assembly)) return;

            var types = Assembly.Load(_conf.ApplicationInit.Assembly).GetTypes().Where(w => w.BaseType != null && w.BaseType.Name == typeof(ApplicationInit).Name);
            if (types.Count() > 1) throw new Exception("系统全局初始化只能初始化一次");

            foreach (var type in types)
            {
                var instance = Activator.CreateInstance(type) as ApplicationInit;
                instance?.OnApplicationStart();
            }
        }
    }
}
